﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace SimpleTestFrameForNFC
{
    class PCI1733And1734
    {
        //1734、1733相关变量定义
        int ErrCde;
        String szErrMsg = string.Empty;  //String * 80
        int DeviceHandle1734;
        int DeviceHandle1733;
        uint DeviceNum = 0;    //1734板号
        uint UIntDeviceNum1733 = 1; //1733板号

        /******************* 非托管DLL调用*****************/
        //每个驱动函数都会返回一个状态代码标识此函数是否成功执行. 当函数返回的代码非0，表示此函数执行失败.

        /// <summary>
        /// 打开设备，由设备号得到设备句柄  
        /// </summary>
        /// <param name="DeviceNum">设备号</param>
        /// <param name="DriverHandle">设备句柄</param>
        /// <returns>成功或错误号</returns>
        [DllImport("Adsapi32.dll")]
        public static extern int DRV_DeviceOpen(uint DeviceNum, ref int DriverHandle);

        /// <summary>
        /// 获得错误消息，获得指定错误号的错误消息  
        /// </summary>
        /// <param name="lError">驱动程序返回的错误代码</param>
        /// <param name="lpszszErrMsg">用户必须分配至少80字节的空间来保存返回的错误消息。</param>
        [DllImport("Adsapi32.dll")]
        public static extern void DRV_GetErrorMessage(ref Int32 lError, string lpszszErrMsg);

        /// <summary>
        /// 设备句柄DriverHandle 指向的设备上，向某个DO端口写一个字节的数据。 
        /// </summary>
        /// <param name="DriverHandle"></param>
        /// <param name="DioWritePortByte"></param>
        /// <returns></returns>
        [DllImport("Adsapi32.dll")]
        public static extern int DRV_DioWritePortByte(int DriverHandle, ref PT_DioWritePortByte DioWritePortByte);

        /// <summary>
        /// 关闭由设备句柄 DriverHandle 指向的设备，释放为该设备分配的资源。  
        /// </summary>
        /// <param name="DriverHandle">设备句柄</param>
        /// <returns>成功或错误号</returns>
        [DllImport("Adsapi32.dll")]
        public static extern int DRV_DeviceClose(ref int DriverHandle);

        /// <summary>
        /// 在设备句柄 DriverHandle 指向的设备上，读取某个DI 端口的输入状态。 
        /// </summary>
        /// <param name="DriverHandle"></param>
        /// <param name="lpDioReadPortByte"></param>
        /// <returns></returns>
        [DllImport("Adsapi32.dll")]
        public static extern int DRV_DioReadPortByte(int DriverHandle, ref PT_DioReadPortByte lpDioReadPortByte);

        /******************* 结构体申明*****************/
        public struct PT_DioWritePortByte
        {
            public ushort Port;
            public ushort mask;
            public ushort state;

        }
        PT_DioWritePortByte lpDioWritePort = new PT_DioWritePortByte();

        /// <summary>
        /// 端口号及其8位DI端口状态
        /// </summary>
        public struct PT_DioReadPortByte
        {
            public ushort Port;
            public IntPtr Value;
        }
        PT_DioReadPortByte lpDioReadPort = new PT_DioReadPortByte();

        /// <summary>
        /// 继电器控制函数
        /// </summary>
        /// <param name="iPort"></param>
        /// <param name="cState"></param>
        public void RelaycontrolFull(ushort iPort, String cState)
        {
            ushort iState;

            iState = (ushort)Convert.ToInt32(cState, 2);

            lpDioWritePort.Port = iPort;
            lpDioWritePort.mask = 255;
            lpDioWritePort.state = iState;
            ErrCde = DRV_DioWritePortByte(DeviceHandle1734, ref lpDioWritePort);

            if (ErrCde != 0)
            {
                DRV_GetErrorMessage(ref ErrCde, szErrMsg);
            }
        }

        public int GetBitStatus(ushort portNo, ushort bitNo)
        {
            byte PortState = 0;

            lpDioReadPort.Port = portNo;
            lpDioReadPort.Value = Marshal.AllocHGlobal(sizeof(ushort));
            ErrCde = DRV_DioReadPortByte(DeviceHandle1733, ref lpDioReadPort);
            if (ErrCde != 0)
            {
                DRV_GetErrorMessage(ref ErrCde, szErrMsg);
                return -1;
            }

            PortState = Marshal.ReadByte(lpDioReadPort.Value);

            int byteBitNO = 1;
            for (int i = 0; i < bitNo; i++)
            {
                byteBitNO = 2 * byteBitNO;
            }

            if ((PortState & byteBitNO) == byteBitNO)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }

        public int connect()
        {
            ErrCde = DRV_DeviceOpen(UIntDeviceNum1733, ref DeviceHandle1733);
            if (ErrCde != 0)
            {
                DRV_GetErrorMessage(ref ErrCde, szErrMsg);
                return ErrCde;
            }

            ErrCde = DRV_DeviceOpen(DeviceNum, ref DeviceHandle1734);
            if (ErrCde != 0)
            {
                DRV_GetErrorMessage(ref ErrCde, szErrMsg);
                return ErrCde;
            }

            return 0;
        }
    }
}
